package baoycode.view;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import baoycode.db.MetaBuilder;
import baoycode.db.TableMeta;
import baoycode.model.DataSourceBean;
import baoycode.utils.DBUtils;
import baoycode.utils.FreeMakerUtils;
import baoycode.utils.I18n;
import baoycode.utils.PathUtils;
import baoycode.utils.SerializeUtils;
import baoycode.utils.StringUtils;
import baoycode.utils.ViewCreator;

public class TemplateView extends TitleAreaDialog {

	public TemplateView(Shell shell) {
		super(shell);
	}
	

	@Override
	protected Control createDialogArea(Composite parent) {
		super.setMessage(I18n.sqlTitle + "TableMeta[name,modelName,ColumnMeta[name,javaType,attrName]]",
				IMessageProvider.INFORMATION);
		Composite area = (Composite) super.createDialogArea(parent);
		Composite container = new Composite(area, SWT.NULL);
		GridLayout layout = new GridLayout(3, false);
		layout.verticalSpacing = 10;
		container.setLayout(layout);

		connectionBtn = new List(container, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
		connectionBtn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				if (connectionBtn.getSelectionIndex() == -1)
					return;
				if (connectionBtn.getSelectionIndex() == currentTableIndex)
					return;
				currentTableIndex = connectionBtn.getSelectionIndex();
				int i = 0;
				for (DataSourceBean d : dataSourceBeans) {
					if (i == connectionBtn.getSelectionIndex()) {
						selectedDataSource = d;
						break;
					}
					i++;
				}
				tables.setItems(DBUtils.getTables(selectedDataSource));
				new Thread(new Runnable() {
					@Override
					public void run() {
						tableMetas = new MetaBuilder(DataSourceBean.toDataSource(selectedDataSource)).build();
					}
				}).start();
			}
		});
		GridData connectionsStyle = new GridData(GridData.FILL_BOTH);
		connectionsStyle.heightHint = 400;
		connectionsStyle.widthHint = 100;
		connectionBtn.setLayoutData(connectionsStyle);

		connectionBtn.setItems(DataSourceBean.getNames(dataSourceBeans));

		tables = new List(container, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
		tables.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				selectTables = tables.getSelection();
			}
		});
		GridData tablesStyle = new GridData(GridData.VERTICAL_ALIGN_FILL);
		tablesStyle.heightHint = 400;
		tablesStyle.widthHint = 150;
		tables.setLayoutData(tablesStyle);

		Composite formPanel = new Composite(container, SWT.FILL);
		GridData formPanelStyle = new GridData(GridData.FILL_BOTH);
		formPanel.setLayoutData(formPanelStyle);
		formPanel.setLayout(new GridLayout(3, false));

		Label comboLabel = new Label(formPanel, SWT.NULL);
		comboLabel.setText("模板");

		combo = new Combo(formPanel, SWT.BORDER | SWT.SINGLE);
		combo.setItems(new String[] { "entity", "entity-hibernate" });
		combo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String selectedText = combo.getText();
				if (StringUtils.isNotBlank(selectedText)) {
					InputStream in = getClass().getResourceAsStream("tpl/"  + selectedText + ".ftl");
					String tplcontent = "";
					if (in != null) {
						try {
							tplcontent = IOUtils.toString(in, "UTF-8");
						} catch (IOException e1) {
							e1.printStackTrace();
						} finally {
							try {
								in.close();
							} catch (IOException e1) {
								e1.printStackTrace();
							}
						}
					}
					tplContent.setText(tplcontent);
				}
			}
		});
		new Label(formPanel, SWT.NULL);

		Label isUpdateTplLabel = new Label(formPanel, SWT.LEFT);
		isUpdateTplLabel.setText("修改");
		isUpdateTpl = new Button(formPanel, SWT.CHECK);
		isUpdateTpl.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				tplContent.setEnabled(isUpdateTpl.getSelection());
			}
		});
		new Label(formPanel, SWT.NULL);

		Label label = new Label(formPanel, SWT.LEFT);
		GridData labelStyle = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		labelStyle.widthHint = 30;
		label.setLayoutData(labelStyle);
		label.setText(I18n.tpl);
		tplContent = new Text(formPanel, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
		tplContent.setEnabled(false);
		GridData tplContentStyle = new GridData(GridData.FILL_VERTICAL);
		tplContentStyle.heightHint = 150;
		tplContentStyle.widthHint = 600;
		tplContent.setLayoutData(tplContentStyle);
		new Label(formPanel, SWT.NULL);

		Label label2 = new Label(formPanel, SWT.LEFT);
		GridData labelStyle2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		labelStyle2.widthHint = 30;
		label2.setLayoutData(labelStyle2);
		label2.setText(I18n.packageName);
		packageName = new Text(formPanel, SWT.BORDER);
		packageName.setText("com.baoy");
		packageName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		new Label(formPanel, SWT.NULL);

		Label label3 = new Label(formPanel, SWT.NULL);
		label3.setText(I18n.dic);
		// Text
		browser = new Text(formPanel, SWT.BORDER | SWT.SINGLE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		browser.setLayoutData(gd);
		// Button
		Button button = new Button(formPanel, SWT.PUSH);
		button.setText(I18n.choose);
		button.addSelectionListener(new ViewCreator.BrowseSelectionAdapter(getShell(), "", browser));
		return area;
	}

	@Override
	protected int getShellStyle() {
		return super.getShellStyle() | SWT.MIN | SWT.MAX | SWT.RESIZE;
	}

	/**
	 * 初始化对话框
	 */
	@Override
	@SuppressWarnings("unchecked")
	protected void configureShell(Shell newShell) {
		dataSourceBeans = (Set<DataSourceBean>) SerializeUtils.deserializeDecoder(PathUtils.getDataSourceFile());
		if (dataSourceBeans == null) {
			dataSourceBeans = new HashSet<DataSourceBean>();
		}
		super.configureShell(newShell);
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		// super.createButtonsForButtonBar(parent);
		// createButton(parent, IDialogConstants.CANCEL_ID, I18n.cancel, false);
	}

	// public static void main(String[] args) {
	// DataSourceBean selectedDataSource = new DataSourceBean();
	// selectedDataSource.setDbName("manager_test");
	// selectedDataSource.setUrl("jdbc:mysql://172.16.8.35:3306/manager_test?useUnicode=true&amp;characterEncoding=UTF-8");
	// selectedDataSource.setUser("root");
	// selectedDataSource.setPassword("root");
	// selectedDataSource.setDriver("com.mysql.jdbc.Driver");
	//
	// java.util.List<TableMeta> tableMetas = new
	// MetaBuilder(DataSourceBean.toDataSource(selectedDataSource)).build();
	// TableMeta tableMeta = TableMeta.getTableMetaByName(tableMetas,
	// "audit_data_rec");
	// Map<String, Object> data = new HashMap<String, Object>();
	// data.put("tableMeta", tableMeta);
	// data.put("packageName", "org.springside");
	// FreeMakerUtils.generateFile(FreeMakerUtils.getFreeMarkerCfg(TemplateView.class,
	// "tpl"), "entity-hibernate.ftl",
	// data, "/Users/zeroleavebaoyang/git/baoycode/src/baoycode/view/",
	// tableMeta.modelName + ".java");
	// System.out.println(tableMeta);
	// }

	public void genCode() {
		if (StringUtils.isBlank(combo.getText())) {
			MessageDialog.openInformation(getShell(), "FAIL", I18n.alertCombo);
			return;
		}
        if (selectTables != null && selectTables.length > 0) {
        	boolean r = false;
            for (String selectTable : selectTables) {
                TableMeta tableMeta = TableMeta.getTableMetaByName(tableMetas, selectTable);
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("tableMeta", tableMeta);
                data.put("packageName", packageName.getText());
                // 根据修改后的模板
                if (isUpdateTpl.getSelection() && StringUtils.isNotBlank(tplContent.getText())) {
                    if (FreeMakerUtils.generateFile(new StringReader(tplContent.getText()), data,
                            getBaseModelOutputDir_() + File.separator + tableMeta.modelName
                                    + ".java")) {
                    	r = true;
                    }	
                } else {
                    if (FreeMakerUtils.generateFile(
                            FreeMakerUtils.getFreeMarkerCfg(this.getClass(), "tpl"),
                            combo.getText() + ".ftl", data,
                            getBaseModelOutputDir_() + File.separator,
                            tableMeta.modelName + ".java")) {
                    	r = true;
                    }
                }
            }
            if (r) MessageDialog.openInformation(getShell(), "SUCC", I18n.saveSucc);
        }
	}

	protected Control createButtonBar(Composite parent) {
		Composite container = (Composite) super.createButtonBar(parent);
		Button btnFormat = createButton(container, 111, I18n.btnGen, true);
		btnFormat.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				genCode();
			}
		});
		createButton(container, 115, I18n.cancel, true).addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				close();
			}
		});
		return container;
	}

	public String getBaseModelOutputDir_() {
		Text t = this.browser;
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource res = root.findMember(new Path(t.getText().trim()));
		if (res.exists() && (res instanceof IContainer)) {
			return res.getLocationURI().toString().replace("file:", "");
		}
		return null;
	}

	List connectionBtn;
	List tables;
	Set<DataSourceBean> dataSourceBeans;
	DataSourceBean selectedDataSource;
	String[] selectTables;
	int currentTableIndex = -1;
	Text tplContent;
	Text browser;
	Button isUpdateTpl;
	Combo combo;
	Text packageName;

	// 获取该数据库中所有的表以及字段信息
	java.util.List<TableMeta> tableMetas;
}
